package com.capinfo.accumulation.service.collection.impl;

import com.capinfo.accumulation.message.model.collection.PayInInventoryMessage;
import com.capinfo.accumulation.model.collection.Company;
import com.capinfo.accumulation.model.collection.CompanyAccountFund;
import com.capinfo.accumulation.model.collection.Payininfo;
import com.capinfo.accumulation.model.collection.PersonAccountFund;
import com.capinfo.accumulation.parameter.collection.CompanyParameter;
import com.capinfo.accumulation.parameter.collection.PayininfoParameter;
import com.capinfo.accumulation.service.collection.CompanyAccountFundService;
import com.capinfo.accumulation.service.collection.CompanyService;
import com.capinfo.accumulation.service.collection.PayininfoService;
import com.capinfo.accumulation.service.collection.PersonAccountFundService;
import com.capinfo.components.kafka.producer.SimpleProducer;
import com.capinfo.framework.dao.SearchCriteriaBuilder;
import com.capinfo.framework.dao.impl.restriction.RestrictionExpression;
import com.capinfo.framework.service.impl.CommonsDataOperationServiceImpl;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by wcj on 2017/10/24.
 */
public class PayininfoServiceImpl extends CommonsDataOperationServiceImpl<Payininfo, PayininfoParameter> implements PayininfoService {
    @Autowired
    private CompanyAccountFundService companyAccountService;
    @Autowired
    private PersonAccountFundService personAccountService;
    @Autowired
    private SimpleProducer<Object, PayInInventoryMessage> payInInventoryProducer;

    @Override
    public boolean confirm(PayininfoParameter parameter) {
        SearchCriteriaBuilder<Payininfo> searchCriteriaBuilder = new SearchCriteriaBuilder<Payininfo>(Payininfo.class);


        searchCriteriaBuilder.addQueryCondition("companyAccount", RestrictionExpression.EQUALS_OP, parameter.getCompanyAccot());

        searchCriteriaBuilder.addQueryCondition("verificationOptions",RestrictionExpression.EQUALS_OP,parameter.getVerificationOptions());

        searchCriteriaBuilder.addQueryCondition("id",RestrictionExpression.EQUALS_OP,parameter.getEntity().getId());
        String format = new SimpleDateFormat("yyyy-MM-dd").format(parameter.getRemitDate());
        searchCriteriaBuilder.addQueryCondition("receivedDate",RestrictionExpression.EQUALS_OP,format);
        searchCriteriaBuilder.addQueryCondition("isfinished",RestrictionExpression.EQUALS_OP,false);
        List<Payininfo> payininfos = getGeneralService().getObjects(searchCriteriaBuilder.build());
        if(payininfos!=null&&payininfos.size()>0){
            for(Payininfo payininfo:payininfos){
                payininfo.setIsfinished(true);

                this.saveOrUpdate(payininfo);
                payInInventoryProducer.send(1, new PayInInventoryMessage(payininfo.getId(),payininfo.getCompanyAccount(),payininfo.getCompanyAccountFundId()));
            }
            return true;
        }
        return false;
    }

    @Override
    public List<Payininfo> searchPayinfouncheck(PayininfoParameter parameter) {
        SearchCriteriaBuilder<Payininfo> searchCriteriaBuilder = new SearchCriteriaBuilder<Payininfo>(Payininfo.class);

        searchCriteriaBuilder.addQueryCondition("companyAccount", RestrictionExpression.EQUALS_OP, parameter.getCompanyAccot());

        searchCriteriaBuilder.addQueryCondition("verificationOptions",RestrictionExpression.EQUALS_OP,parameter.getVerificationOptions());

        searchCriteriaBuilder.addQueryCondition("isfinished",RestrictionExpression.EQUALS_OP,false);
        List<Payininfo> payininfos = getGeneralService().getObjects(searchCriteriaBuilder.build());


        return payininfos;
    }

    //创建汇缴清册
    @Override
    public boolean buildPayininfoQc(PayininfoParameter parameter,String operator) {
        List<CompanyAccountFund> companyAccountByCretier = companyAccountService.getCompanyAccountByCretier(parameter.getEntity().getCompanyAccount(), parameter.getEntity().getVerificationOptions());
         if(companyAccountByCretier!=null&&companyAccountByCretier.size()>0){
             List<PersonAccountFund> personAccountFunds = personAccountService.queryByCompanyAccountId(companyAccountByCretier.get(0).getId());
             double totalMonthPay = companyAccountByCretier.get(0).getTotalMonthPay().doubleValue();
              Long payWorkerNum = companyAccountByCretier.get(0).getPayWorkerNum();

             double account=0;
             for(PersonAccountFund personAccount:personAccountFunds){

                 account+=personAccount.getPerson().getWageIncome().doubleValue()*(personAccount.getCompanyPaymentRatio()+personAccount.getPersonPaymentRatio());


             }
             long remitNumber=personAccountFunds.size();
             long   increseNum=0;
             long  reduceNum=0;
             if (remitNumber>=payWorkerNum){
                 increseNum=remitNumber-payWorkerNum;
             }else{
                 reduceNum=payWorkerNum-remitNumber;
             }
             double increseAmount=0;
             double reduceAmount=0;
             if(totalMonthPay>=account){
                  reduceAmount=totalMonthPay-account;
             }else{
                  increseAmount=account-totalMonthPay;
             }

             try {
                 Date startDate=null;
                 Date endDate=null;
                 if(!StringUtils.isBlank(parameter.getStartPaymentDate())){
                     startDate = new SimpleDateFormat("yyyyMM").parse(parameter.getStartPaymentDate());
                 }
                 if(!StringUtils.isBlank(parameter.getEndPaymentDate())){
                     endDate = new SimpleDateFormat("yyyyMM").parse(parameter.getEndPaymentDate());
                 }
                 Calendar dd = Calendar.getInstance();
                 dd.setTime(startDate);
                   if (startDate.getTime()<=endDate.getTime()) {
                       while (dd.getTime().before(endDate)||dd.getTime().equals(endDate)) {
                           SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");
                           String paymentDate = dateFormat.format(dd.getTime());
                           Payininfo payinfo = new Payininfo();
                          if(parameter.getEntity().getId()!=null){
                              payinfo.setId(parameter.getEntity().getId());
                          }
                           payinfo.setPayMonthly(paymentDate);

                           payinfo.setCreateName(operator);
                           payinfo.setDateTime(new Date());
                           payinfo.setCompanyAccount(parameter.getEntity().getCompanyAccount());
                           payinfo.setIsfinished(false);
                           payinfo.setRemitAmount(new BigDecimal(Double.valueOf(account)));
                           payinfo.setRemitNumber(remitNumber);
                           payinfo.setSiteId(parameter.getEntity().getSiteId());
                           payinfo.setVerificationOptions(parameter.getEntity().getVerificationOptions());
                           payinfo.setLastRemitAmount(new BigDecimal(Double.valueOf(totalMonthPay)));
                           payinfo.setLastRemitNumber(payWorkerNum);
                           payinfo.setIncreaseRemitAmount(new BigDecimal(Double.valueOf(increseAmount)));
                           payinfo.setIncreaseRemitNumber(increseNum);
                           payinfo.setReduceRemitAmount(new BigDecimal(Double.valueOf(reduceAmount)));
                           payinfo.setReduceRemitNumber(reduceNum);
                           payinfo.setCompanyAccountFundId(companyAccountByCretier.get(0).getId());
                           payinfo.setReceivedDate(parameter.getEntity().getReceivedDate());

                           this.saveOrUpdate(payinfo);
                           dd.add(Calendar.MONTH, 1);
                       }
                       return true;
                   }
             }
             catch (Exception e){
                 e.getStackTrace();
             }
            


         }
        return  false;
    }

    @Override
    public SearchCriteriaBuilder<Payininfo> getSearchCriteriaBuilder(PayininfoParameter parameter) {
        SearchCriteriaBuilder<Payininfo> searchCriteriaBuilder = super.getSearchCriteriaBuilder(parameter);
        searchCriteriaBuilder.addQueryCondition("siteId", RestrictionExpression.EQUALS_OP,parameter.getEntity().getSiteId());
        searchCriteriaBuilder.addQueryCondition("companyAccount",RestrictionExpression.EQUALS_OP,parameter.getEntity().getCompanyAccount());
        if(parameter.getCompanyAccount()!=null){
            searchCriteriaBuilder.addQueryCondition("companyAccountFund.unitName", RestrictionExpression.LIKE_OP, parameter.getCompanyAccount().getUnitName());
        }

        searchCriteriaBuilder.addQueryCondition("verificationOptions",RestrictionExpression.EQUALS_OP,parameter.getEntity().getVerificationOptions());
        searchCriteriaBuilder.addQueryCondition("payMonthly",RestrictionExpression.GREATER_EQUALS_OP,parameter.getStartPaymentDate());

        searchCriteriaBuilder.addQueryCondition("payMonthly",RestrictionExpression.LESS_EQUALS_OP,parameter.getEndPaymentDate());
        if(parameter.getStartReceivedDate()!=null) {
            String sformat = new SimpleDateFormat("yyyy-MM-dd").format(parameter.getStartReceivedDate());
            searchCriteriaBuilder.addQueryCondition("receivedDate", RestrictionExpression.GREATER_EQUALS_OP, sformat);
        }
        if(parameter.getEndReceivedDate()!=null) {
            String eformat = new SimpleDateFormat("yyyy-MM-dd").format(parameter.getEndReceivedDate());
            searchCriteriaBuilder.addQueryCondition("receivedDate", RestrictionExpression.LESS_EQUALS_OP, eformat);
        }
        searchCriteriaBuilder.addQueryCondition("isfinished",RestrictionExpression.EQUALS_OP,parameter.getEntity().getIsfinished());
        return searchCriteriaBuilder;
    }

    @Override
    public boolean cancel(PayininfoParameter parameter) {
        SearchCriteriaBuilder<Payininfo> searchCriteriaBuilder = new SearchCriteriaBuilder<Payininfo>(Payininfo.class);

        searchCriteriaBuilder.addQueryCondition("companyAccount", RestrictionExpression.EQUALS_OP, parameter.getCompanyAccot());

        searchCriteriaBuilder.addQueryCondition("verificationOptions",RestrictionExpression.EQUALS_OP,parameter.getVerificationOptions());

        searchCriteriaBuilder.addQueryCondition("id",RestrictionExpression.EQUALS_OP,parameter.getEntity().getId());
        String format = new SimpleDateFormat("yyyy-MM-dd").format(parameter.getRemitDate());
        searchCriteriaBuilder.addQueryCondition("receivedDate",RestrictionExpression.EQUALS_OP,format);
        searchCriteriaBuilder.addQueryCondition("isfinished",RestrictionExpression.EQUALS_OP,false);
        List<Payininfo> payininfos = getGeneralService().getObjects(searchCriteriaBuilder.build());
        if(payininfos!=null&&payininfos.size()>0){
            for(Payininfo payininfo:payininfos){
                parameter.setEntity(payininfo);
                this.delete(parameter);
            }
            return true;
        }
        return false;
    }

    @Override
    public CompanyAccountFund getCompanyAccount(PayininfoParameter parameter) {
        SearchCriteriaBuilder<Payininfo> searchCriteriaBuilder = new SearchCriteriaBuilder<Payininfo>(Payininfo.class);
        //组织机构代码
        searchCriteriaBuilder.addQueryCondition("companyAccount", RestrictionExpression.EQUALS_OP, parameter.getCompanyAccot());
        //信用代码



//        searchCriteriaBuilder.addQueryCondition("natureAccount.name", RestrictionExpression.EQUALS_OP, "基本");
        Payininfo byCriteria = getGeneralService().getObjectByCriteria(searchCriteriaBuilder.build());



        return byCriteria.getCompanyAccountFund();
    }
}
